package kz.asoft;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;

import kz.asoft.am.common.RisksAppModule;
import kz.asoft.utils.ADFUtils;
import kz.asoft.utils.Utils;

import oracle.adf.model.AttributeBinding;
import oracle.adf.model.BindingContext;
import oracle.adf.view.rich.component.rich.RichPopup;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.component.rich.input.RichSelectBooleanRadio;
import oracle.adf.view.rich.component.rich.input.RichSelectOneChoice;
import oracle.adf.view.rich.component.rich.layout.RichShowDetailItem;
import oracle.adf.view.rich.component.rich.nav.RichCommandToolbarButton;
import oracle.adf.view.rich.render.ClientEvent;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import oracle.jbo.Key;
import oracle.jbo.Row;
import oracle.jbo.RowSetIterator;
import oracle.jbo.ViewObject;
import oracle.jbo.domain.Number;
import oracle.jbo.uicli.binding.JUCtrlValueBinding;

import org.apache.myfaces.trinidad.event.DisclosureEvent;


public class RiskManageBean {
    private String ratioValue;
    private String operString;
    private RichSelectOneChoice selectedOperItem;
    private RichInputText value2InputText;
    private RichInputText value1InputText;
    private RichInputText listValue1InputText;
    private RichInputText listValue2InputText;
    private RichSelectBooleanRadio valuesRadioBox;
    private RichSelectBooleanRadio listValuesRadioBox;
    private Boolean isSelectedRadioListValues;
    private RichPopup deleteRiskPopup;

    public BindingContainer getBindings() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

    /**
     * Создание нового риска
     */
    public String addRisk() {
        if(!validateRiskForm()) {
            FacesMessage message = new FacesMessage(Utils.getLocalizedText("REQUIRED_MESSAGE_RISK_FORM_VALUES"));
            message.setSeverity(FacesMessage.SEVERITY_ERROR);
            FacesContext fc = FacesContext.getCurrentInstance();
            fc.addMessage(null, message);
            return null;
        }
        
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        appModule.addRisk();
        
        ViewObject riskList = appModule.findViewObject("GRisksCurrentView1");
        riskList.executeQuery();

        return "back";
    }
    
    private Boolean validateRiskForm() {
        int errors = 0;

        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        ViewObject riskVO = appModule.findViewObject("GRisksEditView1");
        Row riskForm = riskVO.getCurrentRow();
        errors += riskForm.getAttribute("NameRu") != null ? 0 : 1;
        errors += riskForm.getAttribute("NameKz") != null ? 0 : 1;
        errors += riskForm.getAttribute("DescRu") != null ? 0 : 1;
        errors += riskForm.getAttribute("DescKz") != null ? 0 : 1;
        
        ViewObject createValVO = appModule.findViewObject("SRiskCreateValuesView1");
        RowSetIterator valuesRS = createValVO.createRowSetIterator(null);
        
        while(valuesRS.hasNext()) {
            Row r = valuesRS.next();
            if (r.getAttribute("Oper") != null) {
                errors += r.getAttribute("Oper") != null ? 0 : 1;
                errors += r.getAttribute("Value1") != null ? 0 : 1;
                if (r.getAttribute("Oper").equals((6))) {
                    errors += r.getAttribute("Value2") != null ? 0 : 1;
                }
            } else {
                errors += r.getAttribute("ListValNameRu") != null ? 0 : 1;
                errors += r.getAttribute("ListValNameKz") != null ? 0 : 1;
            }
        }
        
        return errors == 0;
    }
    
    /**
     * Редактирование риска
     * @param actionEvent
     */
    public void editRisk(ActionEvent actionEvent) {
        clearInputForm();
        
        Row row = getCurrentSelectedRow("GRisksCurrentView1");
        Number riskId = (Number) row.getAttribute("Id");
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        
        ViewObject riskEditList = appModule.findViewObject("GRisksEditView1");
        riskEditList.setWhereClause("GRisksModel.ID = " + riskId);
        riskEditList.executeQuery();
        
        ViewObject riskCreateValues = appModule.findViewObject("SRiskCreateValuesView1");
        
        ViewObject riskValueVO = appModule.findViewObject("SRiskValuesView2");
        riskValueVO.setWhereClause("RISK_ID = " + riskId);
        riskValueVO.setOrderByClause("RISK_GROUP_ID");
        riskValueVO.executeQuery();
        
        ViewObject riskListValueVO = appModule.findViewObject("SRiskListValuesView2");
        riskListValueVO.setWhereClause("RISK_ID = " + riskId);
        riskListValueVO.setOrderByClause("RISK_GROUP_ID");
        riskListValueVO.executeQuery();
        
        riskValueVO.reset();
        riskListValueVO.reset();
        while(riskValueVO.hasNext()) {
            Row r = riskValueVO.next();
            riskCreateValues.reset();
            while(riskCreateValues.hasNext()) {
                Row riskCreateValView = riskCreateValues.next();
                if (r.getAttribute("RiskGroupId").equals(riskCreateValView.getAttribute("Id"))) {
                    riskCreateValView.setAttribute("Value1", r.getAttribute("Value1"));
                    riskCreateValView.setAttribute("Oper", r.getAttribute("Oper"));
                    riskCreateValView.setAttribute("Value2", r.getAttribute("Value2"));
                    if (r.getAttribute("RiskListValueId") != null) {
                        Row riskListValues = riskListValueVO.next();
                        riskCreateValView.setAttribute("ListValNameKz", riskListValues.getAttribute("NameKz"));
                        riskCreateValView.setAttribute("ListValNameRu", riskListValues.getAttribute("NameRu"));
                    }
                }
            }
        }
        ViewObject riskList = appModule.findViewObject("GRisksCurrentView1");
        riskList.executeQuery();
    }
    
    public void clearInputForm() {
        RisksAppModule appModule = (RisksAppModule)ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        ViewObject inputFrom = appModule.findViewObject("GRisksEditView1"); 
        ViewObject riskCreateValues = appModule.findViewObject("SRiskCreateValuesView1");
        ViewObject riskValueVO = appModule.findViewObject("SRiskValuesView2");
        ViewObject riskListValueVO = appModule.findViewObject("SRiskListValuesView2");
        
        inputFrom.clearCache();
        riskCreateValues.clearCache();
        riskValueVO.clearCache();
        riskListValueVO.clearCache();
    }
    
    /**
     * Удаление риска
     * @param ae
     */
    public void deleteRisk(ActionEvent ae) {
        hidePopup(ae);
        Row row = getCurrentSelectedRow("GRisksCurrentView1");
        Number riskId = (Number) row.getAttribute("Id");
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        
        appModule.deleteRisk(riskId);
        
        ViewObject riskList = appModule.findViewObject("GRisksCurrentView1");
        riskList.executeQuery();
    }
    
    public void hidePopup(ActionEvent ae) {
        RichPopup popup = getDeleteRiskPopup();
        popup.hide();
    }
    
    /**
     * Очистка поля "Значение 2"
     * если оператор не равен -
     */
    public void oprationChangeListener(ValueChangeEvent valueChangeEvent) {
        if (valueChangeEvent.getNewValue() != null && ((Integer)valueChangeEvent.getNewValue()) != 6) {
            FacesContext fctx = FacesContext.getCurrentInstance();
            ELContext elctx = fctx.getELContext();
            ExpressionFactory efactory = fctx.getApplication().getExpressionFactory();
            ValueExpression ve = efactory.createValueExpression(elctx, "#{row}", Object.class);
            JUCtrlValueBinding row = (JUCtrlValueBinding)ve.getValue(elctx);
            row.setAttribute("Value2", null);
            value2InputText.resetValue();
            value2InputText.setDisabled(true);
        } else {
            value2InputText.setDisabled(false);
        }
        value1InputText.setDisabled(false);
    }
    
    public void setRatioValue(String ratioValue) {
        this.ratioValue = ratioValue;
    }

    /**
     * Расчет коэффициента
     */
    public String getRatioValue() {
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        ViewObject groupsVO = appModule.findViewObject("SCtrlObjGroupsView1");
        Row currRow = groupsVO.getCurrentRow();
        if(currRow != null) {
            Number groupId = (Number) currRow.getAttribute("Id");
            Double result = appModule.calculateRatio(groupId);
            ratioValue = String.valueOf(result);
        }
//        FacesContext.getCurrentInstance().renderResponse();
        return ratioValue;
    }
    
    /**
     * Подготовка в восстановлению риска.
     * @param actionEvent
     */
    public void prepareRestoreRisk(ActionEvent actionEvent) {
        Row row = getCurrentSelectedRow("GRisksCurrentView1");
        Number parentId = (Number) row.getAttribute("Id");
        
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        
        ViewObject riskArchiveListVO = appModule.findViewObject("GRisksArchiveByParentView1");
        
        riskArchiveListVO.setNamedWhereClauseParam("parentId", parentId);
        riskArchiveListVO.executeQuery();
    }
            
    public Row getCurrentSelectedRow(String viewName) {
        JUCtrlValueBinding ctrlObjView = ADFUtils.findCtrlBinding(viewName);
        return ctrlObjView.getIteratorBinding().getCurrentRow();
    }

    /**
     * Восстановление риска.
     * @param actionEvent
     */
    public void restoreRisk(ActionEvent actionEvent) {
        Row row = getCurrentSelectedRow("GRisksArchiveByParentView1");
        if (row.getAttribute("Id") != null) {
            Number restoreRiskId = (Number) row.getAttribute("Id");
            
            RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
            appModule.restoreRiskFromArchive(restoreRiskId);
            
            ViewObject riskList = appModule.findViewObject("GRisksCurrentView1");
            riskList.executeQuery();
        }
    }
    
    /**
     * Откат редактирования риска
     * и установка текущей группы объектов контроля
     * @param actionEvent
     */
    public void rollBackRisk(ActionEvent actionEvent) {
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        ViewObject ctrlGroupVO = appModule.findViewObject("SCtrlObjGroupsView1");
        Number groupId = (Number) ctrlGroupVO.getCurrentRow().getAttribute("Id");
        ADFUtils.findOperation("Rollback").execute();
        ctrlGroupVO.setOrderByClause("ID");
        ctrlGroupVO.executeQuery();
        
        Row r = ctrlGroupVO.findByKey(new Key(new Object[]{groupId}), 1)[0];
        ctrlGroupVO.setCurrentRow(r);
    }

    public String getOperString() {
        if (value1InputText.getValue() == null || "".equals(value1InputText.getValue()) && 
                    value2InputText.getValue() == null || "".equals(value2InputText.getValue())) {
            operString = "";
            return operString;
        }
        RisksAppModule appModule = (RisksAppModule) ADFUtils.getApplicationModuleForDataControl("RisksAppModuleDataControl");
        ViewObject vo = appModule.findViewObject("OperListOfValuesView1");
        Row r = vo.getRow(new Key(new Object[]{selectedOperItem.getValue()}));
        if (r != null) {
            operString = r.getAttribute("value").toString();
        }
        return operString;
    }

    public void setSelectedOperItem(RichSelectOneChoice selectedOperItem) {
        this.selectedOperItem = selectedOperItem;
        AttributeBinding att = (AttributeBinding) ADFUtils.getBindingContainer().getControlBinding("Id");
        AttributeBinding operAtt = (AttributeBinding) ADFUtils.getBindingContainer().getControlBinding("Oper");
        if (att.getInputValue() == null && operAtt.getInputValue() == null) {
            this.selectedOperItem.setValue(6);
            operAtt.setInputValue(6);
        }
    }

    public RichSelectOneChoice getSelectedOperItem() {
        return selectedOperItem;
    }
    
    public void setValue1InputText(RichInputText value1InputText) {
        this.value1InputText = value1InputText;
    }

    public RichInputText getValue1InputText() {
        return value1InputText;
    }

    public void setValue2InputText(RichInputText value2InputText) {
        this.value2InputText = value2InputText;
    }

    public RichInputText getValue2InputText() {
        return value2InputText;
    }

    public void riskGroupChangeListener(DisclosureEvent disclosureEvent) {
        RichShowDetailItem tab = (RichShowDetailItem) disclosureEvent.getSource();
        if (tab.isDisclosed()) {
            blockItems();
        }
    }
    
    private void blockItems() {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ELContext elctx = fctx.getELContext();
        ExpressionFactory efactory = fctx.getApplication().getExpressionFactory();
        ValueExpression ve = efactory.createValueExpression(elctx, "#{row}", Object.class);
        JUCtrlValueBinding row = (JUCtrlValueBinding)ve.getValue(elctx);
        
        if (row.getAttribute("ListValNameRu") != null || row.getAttribute("ListValNameKz") != null) {
            valuesRadioBox.setSelected(false);
            listValuesRadioBox.setSelected(true);
            unblockListValue();
        } else {
            listValuesRadioBox.setSelected(false);
            valuesRadioBox.setSelected(true);
            unblockValues();
        }
    }

    public void valuesRadioListener(ValueChangeEvent valueChangeEvent) {
        RichSelectBooleanRadio radio = (RichSelectBooleanRadio)valueChangeEvent.getSource();
        if (radio.isSelected()) {
            listValuesRadioBox.setSelected(false);
            clearListValuesFields();
            unblockValues();
        }
    }
    
    public void listValuesRadioListener(ValueChangeEvent valueChangeEvent) {
        RichSelectBooleanRadio radio = (RichSelectBooleanRadio)valueChangeEvent.getSource();
        if (radio.isSelected()) {
            valuesRadioBox.setSelected(false);
            clearValuesFields();
            unblockListValue();
        }
    }
    
    private void unblockValues() {
        selectedOperItem.setDisabled(false);        
        listValue1InputText.setDisabled(true);
        listValue2InputText.setDisabled(true);
        
        value1InputText.setDisabled(false);
        value2InputText.setDisabled(true);
        if (selectedOperItem.getValue() != null && selectedOperItem.getValue().equals(6)) {
            value2InputText.setDisabled(false);
        }
    }
    
    private void unblockListValue() {
        selectedOperItem.setDisabled(true);  
        value1InputText.setDisabled(true);
        value2InputText.setDisabled(true);
        
        listValue1InputText.setDisabled(false);
        listValue2InputText.setDisabled(false);
    }
    
    private void clearValuesFields() {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ELContext elctx = fctx.getELContext();
        ExpressionFactory efactory = fctx.getApplication().getExpressionFactory();
        ValueExpression ve = efactory.createValueExpression(elctx, "#{row}", Object.class);
        JUCtrlValueBinding row = (JUCtrlValueBinding)ve.getValue(elctx);
        
        row.setAttribute("Value1", null);
        row.setAttribute("Value2", null);
        row.setAttribute("Oper", null);
        
        selectedOperItem.resetValue();
        value1InputText.resetValue();
        value2InputText.resetValue();
    }
    
    private void clearListValuesFields() {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ELContext elctx = fctx.getELContext();
        ExpressionFactory efactory = fctx.getApplication().getExpressionFactory();
        ValueExpression ve = efactory.createValueExpression(elctx, "#{row}", Object.class);
        JUCtrlValueBinding row = (JUCtrlValueBinding)ve.getValue(elctx);
        
        row.setAttribute("ListValNameRu", null);
        row.setAttribute("ListValNameKz", null);
        
        listValue1InputText.resetValue();
        listValue2InputText.resetValue();
    }

    public void setListValue1InputText(RichInputText listValue1InputText) {
        this.listValue1InputText = listValue1InputText;
    }

    public RichInputText getListValue1InputText() {
        return listValue1InputText;
    }

    public void setListValue2InputText(RichInputText listValue2InputText) {
        this.listValue2InputText = listValue2InputText;
    }

    public RichInputText getListValue2InputText() {
        return listValue2InputText;
    }

    public void setValuesRadioBox(RichSelectBooleanRadio valuesRadioBox) {
        this.valuesRadioBox = valuesRadioBox;
    }

    public RichSelectBooleanRadio getValuesRadioBox() {
        return valuesRadioBox;
    }
    
    public void setListValuesRadioBox(RichSelectBooleanRadio listValuesRadioBox) {
        this.listValuesRadioBox = listValuesRadioBox;
    }

    public RichSelectBooleanRadio getListValuesRadioBox() {
        return listValuesRadioBox;
    }

    public void setIsSelectedRadioListValues(Boolean isSelectedRadioListValues) {
        this.isSelectedRadioListValues = isSelectedRadioListValues;
    }

    public Boolean getIsSelectedRadioListValues() {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ELContext elctx = fctx.getELContext();
        ExpressionFactory efactory = fctx.getApplication().getExpressionFactory();
        ValueExpression ve = efactory.createValueExpression(elctx, "#{row}", Object.class);
        JUCtrlValueBinding row = (JUCtrlValueBinding)ve.getValue(elctx);
        
        isSelectedRadioListValues = row.getAttribute("ListValNameRu") != null || row.getAttribute("ListValNameKz") != null;
//        valuesRadioBox.setSelected(!isSelectedRadioListValues);
        return isSelectedRadioListValues;
    }

    public void setDeleteRiskPopup(RichPopup deleteRiskPopup) {
        this.deleteRiskPopup = deleteRiskPopup;
    }

    public RichPopup getDeleteRiskPopup() {
        return deleteRiskPopup;
    }

    public void riskTableDblClick(ClientEvent clientEvent) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        UIViewRoot root = facesContext.getViewRoot();
        RichCommandToolbarButton button = (RichCommandToolbarButton)root.findComponent("r1:pc1:cb19");
        if (button != null) {
            ActionEvent actionEvent = new ActionEvent(button);
            actionEvent.queue();
        }
    }

    public void prepareCreateRisk(ActionEvent actionEvent) {
        clearInputForm();
        BindingContainer bindings = getBindings();
        OperationBinding operationBinding = bindings.getOperationBinding("CreateInsert");
        operationBinding.execute();
    }
}
